#include <iostream>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>

using namespace std;

//测试status的低18位
int main()
{
    pid_t id = fork();
    if (id == 0)
    {
        exit(-1);
    }

    int status = 0;
    wait(&status);
    printf("code: %d, signal: %d\n", (status >> 8) & 0xFF, status & 0x7F);
    return 0;
}

//课堂
//int func()
//{
//    //exit在任意地方调用,都代表终止进程,里面的参数是退出码
//    exit(12);
//    //非main函数return,代表函数的返回值
//    return 123;
//}
//
//int main()
//{
//    //进程退出场景
//    //代码运行完毕,结果正确(0代表success)
//    //代码运行完毕,结果错误(非0代表failed)
//    //代码异常终止(程序崩溃,退出码变得没有意义了)
//    //main函数的return值是进程的退出码
//    //可以通过命令echo $? 查看最近一次进程退出时的退出码
//    
//    //下面通过一段代码查看linux下c++的错误信息有哪些
//    //exit(123);
//    //func();
//    for(int i = 0; i < 200; ++i)
//    {
//        cout << i  << ":" << strerror(i) << endl;
//    }
//    
//    //默认情况下,输出函数不会进行缓冲区的刷新,数据是保存在输出缓冲区中
//    cout << "i am superhero!";
//    sleep(3);
//    //exit或者是return本身就会要求系统进行缓冲区刷新
//    exit(0);
//    //_exit终止进程是强制性的,不会进行进程的后续收尾工作,比如刷新缓冲区
//    _exit(0);
//
//    //main函数return,代表进程终止了
//    //return 0;
//}

//进程退出,OS层面做了什么?
//OS层面,少了一个进程,释放掉它的PCB,mm_struct,页表和各种映射关系
//然后代码和数据加上申请的空间也要被释放掉

//***********************************************课件
//进程退出场景
//代码运行完毕，结果正确
//代码运行完毕，结果不正确
//代码异常终止
//
//进程常见退出方法
//正常终止（可以通过 echo $? 查看进程退出码）：
//1. 从main返回
//2. 调用exit
//3. _exit
//
//异常退出：
//ctrl + c，信号终止
//
//_exit函数
//#include <unistd.h>
//void _exit(int status);
//参数：status 定义了进程的终止状态，父进程通过wait来获取该值
//说明：虽然status是int，但是仅有低8位可以被父进程所用
//所以_exit(-1)时，在终端执行$?发现返回值是255。
//
//exit函数
//exit最后也会调用exit, 但在调用exit之前，还做了其他工作：
//1. 执行用户通过 atexit或on_exit定义的清理函数。
//2. 关闭所有打开的流，所有的缓存数据均被写入
//3. 调用_exit
//实例：
//#include <unistd.h>
//void exit(int status);
//
//return退出
//return是一种更常见的退出进程方法。执行return n等同于执行exit(n),因为调用main的运行时函数会将main的返
//回值当做 exit的参数。
